package com.deco.back.config;

import com.deco.back.properties.ShiroProperties;
import com.deco.back.shiro.DecoAuthenticatingRealm;
import com.deco.back.shiro.UserAuthenticationFilter;
import com.free.ext.shiro.factorybean.CustShiroFilterFactoryBean;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 功能概述:
 * </p>
 * <p>
 * 功能详述:
 * </p>
 */
@Configuration
public class ShiroConfig {
    /*========================================================================*
     *                         Public Fields (公共属性)
     *========================================================================*/

    /*========================================================================*
     *                         Private Fields (私有属性)
     *========================================================================*/

    @Autowired
    private ShiroProperties properties;

    /*========================================================================*
     *                         Construct Methods (构造方法)
     *========================================================================*/

    /*========================================================================*
     *                         Public Methods (公有方法)
     *========================================================================*/

    @Bean
    public DefaultWebSecurityManager securityManager(DecoAuthenticatingRealm shiroRealm, SessionManager sessionManager){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setSessionManager(sessionManager); //SessionManager暂时不指定了，后面想搞个auth2
        securityManager.setRealm(shiroRealm);
        return securityManager;
    }

    @Bean
    public UserAuthenticationFilter userAuthenticationFilter(){
        UserAuthenticationFilter filter = new UserAuthenticationFilter();
        filter.setLoginurls(this.properties.getLoginUrls());
        return filter;
    }

    @Bean(name="shiroFilter")
    public CustShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager, UserAuthenticationFilter userAuthenticationFilter)
    {
        CustShiroFilterFactoryBean shiroFilter = new CustShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        shiroFilter.setLoginUrl(this.properties.getConfigLoginUrl());
        shiroFilter.setSuccessUrl(this.properties.getConfigLoginSuccesUrl());

        Map<String,Filter> filters = new HashMap<>();
        filters.put("authc", userAuthenticationFilter);
        shiroFilter.setFilters(filters);

        if(this.properties.getAuths() != null && this.properties.getAuths().size() >0){
            shiroFilter.setFilterChainDefinitionMap(this.properties.parseAuthsToMap());
        }

        return shiroFilter;
    }

    @Bean
    public DecoAuthenticatingRealm shiroRealm(){
        return new DecoAuthenticatingRealm();
    }


    @Bean
    public SimpleCookie cookie(Environment env)
    {
        SimpleCookie cookie = new SimpleCookie();
        cookie.setName(this.properties.getSessionId());
        if(StringUtils.isNotEmpty(this.properties.getSessionDomain())){
            cookie.setDomain(this.properties.getSessionDomain());
        }
        return cookie;
    }

    @Bean
    public SessionManager sessionManager(SimpleCookie cookie){
        DefaultWebSessionManager sessionManager =  new DefaultWebSessionManager();
        sessionManager.setGlobalSessionTimeout(Long.parseLong(this.properties.getSessionAge()));
        sessionManager.setDeleteInvalidSessions(true);
        sessionManager.setSessionIdCookieEnabled(true);
        sessionManager.setSessionIdCookie(cookie);
        return sessionManager;
    }

    /*========================================================================*
     *                         Private Methods (私有方法)
     *========================================================================*/
}
